package com.webchartserver.core.config;

import com.alibaba.fastjson.JSON;
import com.webchartserver.core.dto.MsgVO;
import com.webchartserver.core.utils.FilterWordsUtil;
import com.webchartserver.msg.dto.Msg;
import com.webchartserver.msg.service.IMsgService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 模块名称：WebSocket-聊天程序消息转发处理类
 * 模块类型：
 * 编码人：高靖博
 * 创建时间：2023/4/14
 * 联系电话：18587388612
 */
@Component
@ServerEndpoint("/wxserver/{wxNumber}")
// ws://loaclhost:9010/wxserver
public class WebSocket {


    static{
        System.out.println("-------------------------------------------------");
        System.out.println("--------------WebSocket服务初始化------------------");
        System.out.println("-------------------------------------------------");
    }

    // 当前客户端的会话对象
    private Session session;

    // 当前客户端的微信号
    private String nowWxNumber;

    // 用来存在线连接用户信息( 线程安全 )
    // key: 微信号  value: 每个客户端的session对象
    private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<String,Session>();

    // 保存每一个连接的客户端对象(在线客户端)
    private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
    /**
     * 当客户端连接时会触发该方法
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("wxNumber") String wxNumber){

        sessionPool.put(wxNumber,session);
        this.session = session;
        this.nowWxNumber = wxNumber;
        webSockets.add(this);
        System.err.println("---客户端连接！[userID:"+wxNumber+"],已有【"+webSockets.size()+"】个客户端！");
    }

    /**
     * 当客户端发送消息给服务器时触发
     * @param msg 客户端发送给服务器的数据内容
     */
    @OnMessage
    public void onMsg(String msg){
        System.err.println("客户端发送消息："+msg);

        // 客户端发送信息的格式为json
        String[] arr = msg.split("@");

        //记录历史信息
        Msg msgData = new Msg();
        msgData.setSendUserID(arr[0]);
        msgData.setSendNickName(arr[1]);
        msgData.setSaveUserID(arr[2]);
        msgData.setSaveNickName(arr[3]);
        msgData.setSaveAndSendTime(new Date());
        msgData.setMsg(arr[4]);

        // 过滤信息
        String newMsg = FilterWordsUtil.changeWord(msg, '*');

        // 转发
        sendOneToOne(msgData.getSaveUserID(),newMsg);

    }

    /**
     * 1对1发送消息方法
     * @param sendToWxNumber 接收人的微信编号
     * @param msg 发送的消息
     */
    public void sendOneToOne(String sendToWxNumber,String msg){

        for(WebSocket webSocket:webSockets){
            if(webSocket.nowWxNumber.equals(sendToWxNumber)){
                webSocket.session.getAsyncRemote().sendText(msg);
                break;
            }
        }


    }

    /**
     * 群发
     * @param sendToIDList 要接受的微信号集合
     * @param msg 要发送的消息
     */
    public void sendOneToMore(List<String> sendToIDList,String msg){
        for(String wxNumber:sendToIDList){
            Session targetSession = sessionPool.get(wxNumber);
            if(targetSession.isOpen()){ // 校验客户端是否存在连接
                targetSession.getAsyncRemote().sendText(msg);
            }else{
                System.err.println("["+wxNumber+"]离线！");
            }
        }
    }

    /**
     * 广播，只要连接到服务器的客户端都可以接收到下平息
     */
    public void sendToAll(String msg){
        // 遍历所有已连接到服务器的集合进行挨个发送信息
        for(WebSocket webSocket:webSockets){
            // 判断客户端是否断开连接
            if(webSocket.session.isOpen()==true){// 还在线
                webSocket.session.getAsyncRemote().sendText(msg);
            }

        }
    }

    /**
     * 客户端断开连接时触发
     */
    @OnClose
    public void onClose(){
        System.err.println("--客户端断开连接");
        webSockets.remove(this);
        sessionPool.remove(this.nowWxNumber);
    }

    /**
     * 当客户端发送消息或服务器端出现异常时触发
     * @param e
     */
    @OnError
    public void onErr(Throwable e){
        e.printStackTrace();
        System.err.println("--WebSocket异常！！！！");
    }


}
